home *** CD-ROM | disk | FTP | other *** search
- /*
- * lookup.c
- *
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <memory.h>
- #include <ctype.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <assert.h>
- #ifdef unix
- #include <unistd.h>
- /* #include <strerror.h>*/
- #define strnicmp strncasecmp
- #else
- #include <io.h>
- #include <dir.h>
- #endif
-
- #include "rockridg.h"
- #include "datadef.h"
-
- #ifndef O_BINARY
- #define O_BINARY 0
- #endif
-
- static void Read(int fd, void *buf, int n, int swap);
- #if 0
- static void _Read(int fd, void *buf, int n, int swap, int line, char *file);
- #define Read(fd, buf, n, swap) _Read((fd), (buf), (n), (swap), __LINE__, __FILE__)
- #endif
-
- #ifdef unix
- static const char datafile[] = "lookup.dat";
- #else
- static const char datafile[] = "/utils/lookup.dat";
- #endif
- char datafileroot[30];
- static char word[256];
- static struct file_header hdr;
- static long rehash6;
- static long rehash16;
- static int fd;
-
- static long
- hash2(const unsigned char *s) {
- unsigned long h, g, r;
- int c;
- int i;
-
- r = h = ((long) s[0] << 16) + (s[1] << 8);
- for (i = 0; s[i] != 0; ++i) {
- h += ((long) s[i] << i) + s[i];
- h ^= h >> i;
- }
- while ((c = *s++) != '\0') {
- h <<= 4;
- h += c;
- g = h & 0xf0000000;
- h ^= g;
- h ^= (g >> 24);
- r ^= h;
- }
- rehash6 = r % 61;
- rehash16 = r % 65521;
- return h % hdr.hash_prime;
- }
-
- static int
- search_file(const char *filename) {
- FILE *fp;
- int rv;
- static char line[257];
- char *s;
- int lc, uc, len;
-
-
- /* fprintf(stderr, "searching file %s\n", filename); */
-
- lc = *word;
- if (islower(lc)) {
- uc = lc + 'A' - 'a';
- } else {
- uc = lc;
- }
- len = strlen(word);
- if ((fp = fopen(filename, "rt")) == NULL) {
- fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno));
- return 0;
- }
- rv = 0;
- while (fgets(line, 256, fp) != NULL) {
- line[255] = '\n';
- line[256] = '\0';
- for (s = line; *s != 0; ++s) {
- if (*s == lc || (*s == uc && isupper(*s))) {
- if (strnicmp(s, word, len) == 0) {
- ++rv;
- printf("%s: %s", filename, line);
- break;
- }
- }
- }
- }
- fclose(fp);
- return rv;
- }
-
- static char *
- lookup_dir(int n) {
- static char path[1024];
- unsigned char buf[300];
- unsigned char *p;
- short dir_num;
- long x;
-
- if (n == 0) {
- #if unix
- path[0] = '.';
- path[1] = '\0';
- #else
- path[0] = '\0';
- #endif
- return path;
- }
- lseek(fd, hdr.dir_table_offset + n * sizeof(long), SEEK_SET);
- Read(fd, &x, sizeof(x), 1);
- lseek(fd, x, SEEK_SET);
- Read(fd, buf, sizeof(buf), 0);
- dir_num = buf[0] + (buf[1] << 8);
- p = lookup_dir(dir_num);
- strcat(p, "/");
- strcat(p, buf + 2);
- return p;
- }
-
- static char *
- lookup_filename(long n) {
- unsigned char buf[300];
- unsigned char *p;
- short dir_num;
-
- lseek(fd, n, SEEK_SET);
- Read(fd, buf, sizeof(buf), 0);
- dir_num = buf[0] + (buf[1] << 8);
- p = lookup_dir(dir_num);
- strcat(p, "/");
- strcat(p, buf + 2);
- return p;
- }
-
- static int
- search_block(int block) {
- int rv, i;
- long *p;
- long b[2];
- int nfiles;
-
- /* fprintf(stderr, "searching_block( %d == %x )\n", block, block); */
- if (lseek(fd, hdr.block_table_offset + block * 4, SEEK_SET) < 0) {
- fprintf(stderr, "lseek <1> failed: %s\n", strerror(errno));
- exit(1);
- }
- Read(fd, &b, sizeof(b), 1);
- if (block == (hdr.num_blocks - 1)) {
- nfiles = hdr.num_files - b[0];
- assert(nfiles > 0);
- } else {
- nfiles = b[1] - b[0];
- assert(nfiles > 0);
- }
- p = malloc(nfiles * sizeof(*p));
- if (lseek(fd, hdr.file_table_offset + (b[0] * 4), SEEK_SET) < 0) {
- fprintf(stderr, "lseek <2> failed: %s\n", strerror(errno));
- exit(1);
- }
- assert(lseek(fd, 0L, SEEK_CUR) ==
- hdr.file_table_offset + (b[0] * 4));
- Read(fd, p, nfiles * 4, 1);
- for (rv = i = 0; i < nfiles; ++i) {
-
- #ifndef unix
- char dir[3];
-
- sprintf(dir, "%c:", getdisk() + 'A');
- rv += search_file(get_real_filename(dir, lookup_filename(p[i])));
- #else
- rv += search_file(lookup_filename(p[i]));
- #endif
- }
- free(p);
- return rv;
- }
-
- static int
- search(unsigned long x) {
- int rv;
- unsigned char p[512];
- int i, j, n, b;
- long offset;
-
- rv = 0;
- offset = x & 0xffffffL;
- switch ((x >> 30) & 0x3) {
-
- case 0:
- lseek(fd, offset, SEEK_SET);
- Read(fd, p, sizeof(p), 0);
- for (i = 0; i < hdr.num_blocks; ++i) {
- if (p[i/8] & (1 << (i % 8))) {
- rv += search_block(i);
- }
- }
- break;
-
- case 1:
- rv = search_block(x & 0xfff);
- break;
-
- case 2:
- rv = search_block(x & 0xfff);
- rv += search_block((x >> 12) & 0xfff);
- break;
-
- case 3:
-
- lseek(fd, offset, SEEK_SET);
- Read(fd, p, sizeof(p), 0);
- j = 0;
- n = p[j++];
- n += ((p[j] & 0x0f) << 8);
- for (i = 1; i < n + 1; ++i) {
- if (i & 1) {
- b = (p[j++] & 0xf0) >> 4;
- b += p[j++] << 4;
- } else {
- b = p[j++];
- b += (p[j] & 0x0f) << 8;
- }
- rv += search_block(b);
- }
- break;
- }
- return rv;
- }
-
- void
- main(int argc, char **argv) {
- unsigned int len;
- unsigned int match;
- unsigned long h;
- unsigned long x;
- unsigned short i;
-
- if (argc != 2) {
- fprintf(stderr,
- "usage: lookup <word>\n"
- " Search a CDROM for all files containing\n"
- " the specified word.\n");
- exit(1);
- }
- strcpy(word, argv[1]);
- len = strlen(word);
- for (i = 0; i < len; ++i) {
- if (isupper(word[i])) {
- word[i] = tolower(word[i]);
- }
- }
- strcpy(datafileroot, "utils/");
- if ((fd = open("utils/lookup.dat", O_RDONLY|O_BINARY)) < 0) {
- fprintf(stderr, "Cannot open %s: %s.\n",
- "utils/lookup.dat", strerror(errno));
- fprintf(stderr,
- "Cd to the root directory of the cdrom and try again.\n");
- exit(1);
- }
-
- Read(fd, &hdr, sizeof(hdr), 1);
- assert(hdr.header_size == sizeof(hdr));
- assert(hdr.filesize == lseek(fd, 0L, SEEK_END));
- h = hash2(word);
- match = 0;
- for (i = 0;; ++i) {
- lseek(fd, (h * 4) + hdr.hash_table_offset, SEEK_SET);
- Read(fd, &x, sizeof(x), 1);
- if (x == 0) {
- break;
- }
- if (((x >> 30) == 1 && ((x >> 12) & 0xffff) == rehash16) ||
- ((x >> 30) != 1 && ((x >> 24) & 0x003f) == rehash6)) {
- match = search(x);
- break;
- }
- h = (h + rehash6 + i) % hdr.hash_prime;
- }
- if (match == 0) {
- printf("sorry, no match\n");
- }
- exit(match == 0);
- }
-
- static void
- Read(int fd, void *buf, int n, int swap) {
-
- assert(n > 0);
- assert(swap == 0 || (n & 3) == 0);
- if (read(fd, buf, n) < 0) {
- fprintf(stderr, "read failed: %s\n", strerror(errno));
- exit(1);
- }
- #ifdef sparc
- if (swap) {
- int i;
- unsigned char c;
- unsigned char *p;
-
- p = buf;
- for (i = 0; i < n; i += 4) {
- c = p[i];
- p[i] = p[i + 3];
- p[i + 3] = c;
- c = p[i + 1];
- p[i + 1] = p[i + 2];
- p[i + 2] = c;
- }
- }
- #endif
- return;
- }
-
- #if defined(sparc) && ! defined(__svr4__)
- const char *
- strerror(error)
- int error;
- {
- static char defaultMsg[32];
- extern int sys_nerr;
- extern char *sys_errlist[];
-
- if ((error < sys_nerr) && (error > 0)) {
- return sys_errlist[error];
- }
- (void) sprintf(defaultMsg, "unknown error (%d)", error);
- return defaultMsg;
- }
- #endif
-
-